package backup

import (
	"database/sql"
	"dump/config"
	"dump/utils"
	"fmt"
	"os"
	"os/exec"
	"strings"

	_ "github.com/go-sql-driver/mysql"
)

func CheckConfig(configFile string) error {
	if _, err := os.Stat(configFile); os.IsNotExist(err) {
		return fmt.Errorf("配置文件不存在: %v", configFile)
	}
	return nil
}

func CheckDumpPath(dumpPath string) error {
	if _, err := os.Stat(dumpPath); err != nil {
		return fmt.Errorf("mysqldump路径不存在: %s", dumpPath)
	}

	cmd := exec.Command(dumpPath, "--version")
	_, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("mysqldump版本检查失败: %v", err)
	}

	return nil
}

func CheckMySQLConnection(cfg *config.MySQLConfig) error {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/?timeout=6s", cfg.User, cfg.Password, cfg.Host, cfg.Port)

	db, err := sql.Open("mysql", dsn)
	if err != nil {
		return fmt.Errorf("数据库连接失败: %v", err)
	}
	defer db.Close()

	// 使用 SHOW GRANTS 获取权限
	rows, err := db.Query("SHOW GRANTS FOR CURRENT_USER()")
	if err != nil {
		return fmt.Errorf("获取权限失败: %v", err)
	}
	defer rows.Close()

	// 需要的权限关键字
	requiredPrivileges := []string{"SELECT", "SHOW VIEW", "REPLICATION CLIENT", "PROCESS", "RELOAD", "LOCK TABLES", "EVENT"}
	hasPrivileges := make(map[string]bool)
	for _, priv := range requiredPrivileges {
		hasPrivileges[priv] = false
	}

	// 解析权限语句
	for rows.Next() {
		var grantStmt string
		if err := rows.Scan(&grantStmt); err != nil {
			return fmt.Errorf("解析权限语句失败: %v", err)
		}

		// 检查每个需要的权限
		for priv := range hasPrivileges {
			if strings.Contains(grantStmt, priv) {
				hasPrivileges[priv] = true
			}
		}
	}

	// 验证是否拥有所有需要的权限
	var missingPrivileges []string
	for priv, has := range hasPrivileges {
		if !has {
			missingPrivileges = append(missingPrivileges, priv)
		}
	}

	if len(missingPrivileges) > 0 {
		return fmt.Errorf("缺少备份所需权限: %s", strings.Join(missingPrivileges, ", "))
	}

	// 检查版本一致性
	var version string
	err = db.QueryRow("SELECT VERSION()").Scan(&version)
	if err != nil {
		return fmt.Errorf("获取MySQL版本失败: %v", err)
	}

	cmd := exec.Command(cfg.DumpPath, "--version")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("获取mysqldump版本失败: %v", err)
	}

	dumpVersion := strings.TrimSpace(string(output))
	if !strings.Contains(dumpVersion, version) {
		utils.Log(utils.WARN, "mysqldump版本(%s)与MySQL版本(%s)不一致", dumpVersion, version)
	} else {
		utils.Log(utils.INFO, "mysqldump版本与MySQL版本一致: %s", version)
	}

	return nil
}
